package com.mydemo.utils.dataUtils.selectUtils;

import com.mydemo.utils.dataUtils.DataOperation;
import com.mydemo.utils.dataUtils.JsonAndFile.FileRW;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.mydemo.utils.dataUtils.JsonAndFile.Deserialize.deserialize;

public class Select<T> implements DataOperation<T> {
    protected Class<T> clazz;
    protected String table;
    private List<QueryCondition> conditions = new ArrayList<>(); // 用于存储查询条件的list

    // 用于表示各种运算符的枚举，使我们可以支持多种比较操作
    private enum Operator {
        EQUALS("equals"), // 等于
        NOT("not"), // 不等于
        LESS_THAN("<"), // 小于
        LESS_THAN_EQUALS("<="), // 小于等于
        GREATER_THAN(">"), // 大于
        GREATER_THAN_EQUALS(">="), // 大于等于
        LIKE("like"), // 模糊匹配，用于字符串搜索
        IN("in"); // 判断是否在给定集合中
        private final String description;
        Operator(String description) {
            this.description = description;
        }
    }

    @Override
    public T execute() {
        return (T) "select";
    }

    /**
     * 构造方法*/
    public Select(Class<T> clazz, String table) {
        this.clazz = clazz;
        this.table = table;
        conditions.add(new QueryCondition(Operator.EQUALS, "isDeleted", 0));
    }
    /**
     * （已废弃）从存储在指定文件中的列表中，查找所有具有给定属性值的实例。注意只能单条件查询
     *
     * @param col    要匹配的属性名。
     * @param object 与指定属性名对应的值，用于匹配实例。
     * @return List<T> 包含所有匹配条件的实例的列表。
     */
    /*
     *   public <T> List<T> select(String col, Object object) {
     *   String jsonRead = FileRW.FileRead(table);// 从指定文件读取JSON数据
     *   List<T> objectList = deserialize(jsonRead, (Class<T>) clazz);// 反序列化JSON数据
     *   List<T> filteredList = new ArrayList<>();// 创建一个新的ArrayList来存储符合条件的对象
     *   for (T item : objectList) {// 遍历objectList中的每个元素
     *       Object fieldValue = getFieldValue(item, col);// 直接访问对象的字段
     *       if (object.equals(fieldValue)) {// 检查当前对象的字段值是否与object匹配
     *           filteredList.add(item);// 如果匹配，将对象添加到filteredList中
     *       }
     *   }
     *   return filteredList;// 返回包含符合条件对象的List
     *  }
     */
    /**
     * 辅助方法，QueryCondition类，用于封装单个查询条件，用于链式查询
     * */
//    private class QueryCondition {
//        private String column;//查询的列
//        private Object value;//查询的内容
//
//        public QueryCondition(String column, Object value) {
//            this.column = column;
//            this.value = value;
//        }//构造函数
//
//        public boolean matches(T item) {
//            Object fieldValue = getFieldValue(item, column);
//            return value.equals(fieldValue);
//        }
//    }

    // 内部类，用于封装单个查询条件
    private class QueryCondition {
        private Operator operator; // 运算符
        private String column; // 查询的列名
        private Object value; // 查询的值

        // 构造函数
        public QueryCondition(Operator operator, String column, Object value) {
            this.operator = operator;
            this.column = column;
            this.value = value;
        }

        // 判断实体对象是否满足当前条件
        public boolean matches(T item) {
            Object fieldValue = getFieldValue(item, column); // 获取字段值
            switch (operator) {
                case EQUALS:
                    return value.equals(fieldValue); // 检查是否等于
                case NOT:
                    return !value.equals(fieldValue); // 检查是否不等于
                case LESS_THAN:
                    if (fieldValue instanceof Comparable && value instanceof Comparable) {
                        return ((Comparable) fieldValue).compareTo(value) < 0; // 检查是否小于
                    }
                    throw new UnsupportedOperationException("小于：比较类型不正确");
                case LESS_THAN_EQUALS:
                    if (fieldValue instanceof Comparable && value instanceof Comparable) {
                        return ((Comparable) fieldValue).compareTo(value) <= 0; // 检查是否小于等于
                    }
                    throw new UnsupportedOperationException("小于等于：比较类型不正确");
                case GREATER_THAN:
                    if (fieldValue instanceof Comparable && value instanceof Comparable) {
                        return ((Comparable) fieldValue).compareTo(value) > 0; // 检查是否大于
                    }
                    throw new UnsupportedOperationException("大于：比较类型不正确");
                case GREATER_THAN_EQUALS:
                    if (fieldValue instanceof Comparable && value instanceof Comparable) {
                        return ((Comparable) fieldValue).compareTo(value) >= 0; // 检查是否大于等于
                    }
                    throw new UnsupportedOperationException("大于等于：比较类型不正确");
                case LIKE:
                    if (fieldValue instanceof String && value instanceof String) {
                        return ((String) fieldValue).contains((String) value); // 检查字符串是否包含
                    }
                    throw new UnsupportedOperationException("模糊查询：该操作只能使用 String 类型");
                case IN:
                    if (value instanceof List) {
                        return ((List) value).contains(fieldValue); // 检查值是否在列表中
                    }
                    throw new UnsupportedOperationException("存在：该操作需要 List 作为类型");
                default:
                    throw new IllegalArgumentException("不支持的操作类型: " + operator);
            }
        }
    }

    /**
     * 辅助方法，用于动态获取对象的字段值
     * 该方法使用反射，允许我们访问对象的私有或受保护的字段
     * item是任何Java对象，fieldName是该对象的一个字段名
     * */
//    private static Object getFieldValue(Object item, String fieldName) {
//        try {
//            Field field = item.getClass().getDeclaredField(fieldName);// 获取item类中名为fieldName的字段
//            field.setAccessible(true);// 设置访问权限，即使该字段是私有的
//            return field.get(item);// 返回字段的值
//        } catch (NoSuchFieldException | IllegalAccessException e) {
//            throw new RuntimeException(e);
//        }
//    }
    private static Object getFieldValue(Object object, String fieldName) {
        if (object == null) {
            return null;
        }
        Class<?> clazz = object.getClass();
        Field field = null;
        while (clazz != null && field == null) {
            try {
                field = clazz.getDeclaredField(fieldName);
            } catch (NoSuchFieldException ignored) {
                clazz = clazz.getSuperclass();
            }
        }
        if (field != null) {
            field.setAccessible(true);
            try {
                return field.get(object);
            } catch (IllegalAccessException e) {
                throw new RuntimeException("无法访问字段值", e);
            }
        } else {
            throw new RuntimeException("无法找到字段 " + fieldName);
        }
    }

    // matchesConditions方法，用于判断实体对象是否满足所有查询条件
    private boolean matchesConditions(T item) {
        // 使用条件列表中的所有条件来判断实体对象是否满足条件
        return conditions.stream()
                .allMatch(condition -> condition.matches(item));
    }
    // execute方法，执行选择操作
    public List<T> end() {
        String jsonRead = FileRW.FileRead(table); // 从指定文件读取JSON数据
        List<T> objectList = deserialize(jsonRead, clazz); // 反序列化JSON数据为实体对象列表
        if (conditions.isEmpty()) { // 如果没有设置查询条件
            return objectList; // 直接返回所有数据
        }
        // 如果设置了查询条件，使用流和过滤器返回符合条件的数据
        return objectList.stream()
                .filter(this::matchesConditions)
                .collect(Collectors.toList());
    }
    // selectAll方法，用于返回所有数据
    public List<T> selectAll() {
        conditions.clear(); // 清除所有查询条件
        return end(); // 调用execute方法返回所有数据
    }

    /**
     * where方法，用于添加查询条件
     * @
     * */
    public Select<T> where(String column, Object value) {
        conditions.add(new QueryCondition(Operator.EQUALS, column, value));// 将条件添加到条件列表中
        return this; // 链式调用，返回当前Select实例
    }
    // 用于添加不等于条件的方法
    public Select<T> not(String column, Object value) {
        conditions.add(new QueryCondition(Operator.NOT, column, value));
        return this;
    }
    // 用于添加LIKE条件的方法
    public Select<T> like(String column, String value) {
        conditions.add(new QueryCondition(Operator.LIKE, column, value));
        return this;
    }
    // 用于添加IN条件的方法
    public Select<T> in(String column, List value) {
        conditions.add(new QueryCondition(Operator.IN, column, value));
        return this;
    }
    // 用于添加小于条件的方法
    public Select<T> lessThan(String column, Comparable value) {
        conditions.add(new QueryCondition(Operator.LESS_THAN, column, value));
        return this;
    }
    // 用于添加小于等于条件的方法
    public Select<T> lessThanOrEqualTo(String column, Comparable value) {
        conditions.add(new QueryCondition(Operator.LESS_THAN_EQUALS, column, value));
        return this;
    }
    // 用于添加大于条件的方法
    public Select<T> greaterThan(String column, Comparable value) {
        conditions.add(new QueryCondition(Operator.GREATER_THAN, column, value));
        return this;
    }
    // 用于添加大于等于条件的方法
    public Select<T> greaterThanOrEqualTo(String column, Comparable value) {
        conditions.add(new QueryCondition(Operator.GREATER_THAN_EQUALS, column, value));
        return this;
    }
    public List<T> endTruly() {
        List<QueryCondition> originalConditions = new ArrayList<>(conditions);
        conditions.removeIf(condition -> Operator.EQUALS == condition.operator &&
                "isDeleted".equals(condition.column) &&
                ((Integer)condition.value).intValue() == 0);
        List<T> result = end(); // 调用原始的end()方法获取数据
        conditions.clear(); // 清空条件列表
        conditions.addAll(originalConditions); // 恢复原来的条件列表
        return result;
    }
}
